//
//  KLMBaseController.swift
//  KLMHomeRoom
//
//  Created by Nic on 2025/2/18.
//

import UIKit

// MARK: - 基础空状态协议
protocol EmptyStateProtocol {
    func showEmptyState(title: String?, image: String?, buttonTitle: String?)
    func hideEmptyState()
    func showEmptyButton() -> Bool
    func customEmptyButton() -> UIButton?
    func configEmptyButton(_ button: UIButton)
}

class KLMBaseController: UIViewController, RowTitleReceivable, EmptyStateProtocol {
    /// 上一页传入的title
    var titleText: String?
    let currentTheme: Theme = KLMThemeManager.shared.currentTheme
    // 记录原始视图位置
    private var originalViewFrame: CGRect = .zero
    // 是否启用自动调整（可被子类重写）
    var enableKeyboardAdjustment: Bool { return true }
    
    // MARK: - 空状态视图组件
    private var emptyStateView: UIView?
    private var emptyButton: UIButton?
    private let emptyStateContainer = UIView()
    lazy var emptyView: KLMEmptyView = {
        var emptyView = KLMEmptyView.loadFromNib()
        return emptyView as! KLMEmptyView
    }()
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        if nibNameOrNil != nil {
            super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        } else {
            // 子类如果有xib，自动加载
            let className = String(describing: Self.self)
            let targetBundle = nibBundleOrNil ?? Bundle(for: type(of: self))
            let nibPath = targetBundle.path(forResource: className, ofType: "nib")
            if nibPath != nil {
                super.init(nibName: className, bundle: targetBundle)
            } else {
                super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
            }
        }
        initConfig()
    }
    
    @MainActor required init?(coder: NSCoder) {
        super.init(coder: coder)
        initConfig()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(themeChanged), name: .themeChanged, object: nil)
        
        viewDidLoadConfig()
        // Do any additional setup after loading the view.
        applyTheme(currentTheme)
        
        if let titleText = titleText {
            title = titleText
        }
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        layoutConfig()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setNavBarStyle()
        registerKeyboardNotifications()
    }
    // MARK: - 手动添加子控件
    func initConfig() {}
    // MARK: - viewDidLoad中做一些配置，applyTheme调用之前
    func viewDidLoadConfig() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        // 设置手势识别器不影响子视图的交互
        tapGesture.cancelsTouchesInView = false
        view.addGestureRecognizer(tapGesture)
    }
    @objc func dismissKeyboard() -> Void {
        view.endEditing(true)
    }
    // MARK: - 布局子控件大小配置
    func layoutConfig() {}
    func setNavBarStyle() { resetNavBarDefaultStyle() }
    // MARK: - 系统显示模式（浅色/深色）变化
    @objc private func themeChanged() { applyTheme(currentTheme) }
    func applyTheme(_ theme: Theme) {
        view.backgroundColor = theme.viewBgColor
    }
    
    /// 创建空状态视图
    func prepareEmptyStateView() {
        emptyStateContainer.translatesAutoresizingMaskIntoConstraints = false
        emptyStateContainer.alpha = 0
        view.addSubview(emptyStateContainer)
        emptyStateContainer.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().offset(-KLM_NavBarHeight)
        }
        emptyStateView = createEmptyView() ?? createDefaultEmptyView()
        setupEmptyStateLayout()
    }
    
    // MARK: - 空状态视图协议方法
    func showEmptyState(title: String? = "暂无数据", image: String? = "empty", buttonTitle: String? = nil) {
//        hideEmptyState()
        prepareEmptyStateView()
        configEmptyState(title: title, image: image, buttonTitle: buttonTitle)
        view.bringSubviewToFront(emptyStateContainer)
        UIView.animate(withDuration: 0.3) {
            self.emptyStateContainer.alpha = 1.0
        }
    }
    
    func hideEmptyState() {
        UIView.animate(withDuration: 0.2) {
            self.emptyStateContainer.alpha = 0.0
        } completion: { _ in
            self.emptyStateContainer.removeFromSuperview()
        }
    }
    func customEmptyButton() -> UIButton? {
        let btn = UIButton(type: .custom)
        btn.configStyle(font: UIFont(safeName: "PingFangSC-Bold", size: 18), titleColor: .white)
        btn.addTarget(self, action: #selector(tapEmptyButton(_:)), for: .touchUpInside)
        btn.layer.cornerRadius = 24
        btn.layer.masksToBounds = true
        btn.backgroundColor = appMainThemeColor
        return btn
    }
    func showEmptyButton() -> Bool {
        return false
    }
    private func configEmptyState(title: String?, image: String?, buttonTitle: String?) {
        if emptyStateView == emptyStateView || emptyStateView!.subviews.contains(emptyView) {
            emptyView.updateContent(image: image, tip: title)
        }
        
        if let emptyButton = emptyButton, let buttonTitle = buttonTitle, !buttonTitle.isEmpty {
            emptyButton.configStyle(with: buttonTitle)
        }
        emptyStateView?.layoutIfNeeded()
    }
    func configEmptyButton(_ button: UIButton) { }
    // MARK: - 默认空状态视图
    private func createDefaultEmptyView() -> UIView {
        if let emptyButton = customEmptyButton(), showEmptyButton() {
            let containerView = UIView()
            containerView.addSubview(emptyView)
            containerView.addSubview(emptyButton)
            
            self.emptyButton = emptyButton
            configEmptyButton(emptyButton)
            
            emptyView.snp.makeConstraints { make in
                make.top.leading.trailing.equalToSuperview()
            }
            emptyButton.snp.makeConstraints { make in
                make.top.equalTo(emptyView.snp.bottom).offset(24)
                make.leading.equalToSuperview().offset(24)
                make.trailing.equalToSuperview().offset(-24)
                make.bottom.equalToSuperview().offset(0)
                make.height.equalTo(48)
            }
            return containerView
        }
        return emptyView
    }
    // MARK: - 自定义空状态视图（返回 nil 则使用默认）
    func createEmptyView() -> UIView? {
        return nil
    }
    // MARK: - 空状态按钮点击事件（子类可重写）
    @objc func tapEmptyButton(_ button: UIButton) { }
    // MARK: - 空状态视图布局
    private func setupEmptyStateLayout() {
        guard let contentView = emptyStateView else { return }
        emptyStateContainer.subviews.forEach { $0.removeFromSuperview() }
        emptyStateContainer.addSubview(contentView)
        contentView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    
    // MARK: - 获取用户最新选中的房间ID
    func getNewestHomeId(homeId: Int?) -> Int? {
        guard let homeId = homeId else {
            return KLMUserDefault.getValue(for: .currentSelectedHomeId) as? Int
        }
        return homeId
    }
    
    // MARK: - 生命周期
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        unregisterKeyboardNotifications()
    }
    
    // MARK: - 键盘监听
    private func registerKeyboardNotifications() {
        guard enableKeyboardAdjustment else { return }
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow(_:)),
            name: UIResponder.keyboardWillShowNotification,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide(_:)),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }
    
    private func unregisterKeyboardNotifications() {
        guard enableKeyboardAdjustment else { return }
        NotificationCenter.default.removeObserver(self)
    }
    
    // MARK: - 键盘事件处理
    @objc private func keyboardWillShow(_ notification: Notification) {
        guard enableKeyboardAdjustment,
              let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
              let firstResponder = findFirstResponder() else { return }
        
        // 计算键盘顶部位置
        let keyboardTop = KLMScreenH - keyboardFrame.height
        
        var firstResponderFrame = firstResponder.convert(firstResponder.bounds, to: view)
        if let window = view.window ?? (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window {
            // 比较window上的间距，而不是view
            firstResponderFrame = firstResponder.convert(firstResponder.bounds, to: window)
        }
        
        // 需要上移的偏移量（增加 20pt 间距）
        let offset = firstResponderFrame.maxY - keyboardTop + 20
        guard offset > 0 else { return }
        
        // 获取动画参数
        let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0.25
        let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        
        // 执行动画
        UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curve), animations: {
            self.view.transform = CGAffineTransform(translationX: 0, y: -offset)
        })
    }
    
    @objc private func keyboardWillHide(_ notification: Notification) {
        guard enableKeyboardAdjustment else { return }
        
        let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0.25
        let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        
        UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: curve), animations: {
            self.view.transform = .identity
        })
    }
    
    // MARK: - 查找第一响应者
    private func findFirstResponder() -> UIView? {
        func findInView(_ view: UIView) -> UIView? {
            if view.isFirstResponder {
                return view
            }
            for subview in view.subviews {
                if let responder = findInView(subview) {
                    return responder
                }
            }
            return nil
        }
        return findInView(self.view)
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
